package com.flca.frw.dao;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.flca.FlcaConstants;
import com.google.inject.Inject;
import com.google.inject.name.Named;


public class ConnPoolsImpl implements ConnPools, FlcaConstants {

	private static Logger logger = LoggerFactory.getLogger(ConnPoolsImpl.class);

	private List<RegisterDatabase> mRegisterDatabases;
	private Map<String, PoolData> mDbsMap;
	
	@Inject
	public ConnPoolsImpl(@Named(REGISTER_DATABASES) List<RegisterDatabase> aRegisterDatabases) {
		super();
		this.mDbsMap = new HashMap<String, PoolData>();
		this.mRegisterDatabases = aRegisterDatabases;
		for (RegisterDatabase registerDatabase : mRegisterDatabases) {
			addDao(registerDatabase);
		}
	}

	@Override
	public void addDao(RegisterDatabase aRegDbs) {
		logger.info("adding databse " + aRegDbs);
		PoolData pooldata = build(aRegDbs);
		mDbsMap.put(aRegDbs.getUnitName(), pooldata);
		pooldata.daoFactory.register(aRegDbs);
	}

	@Override
	public Dao getDao(String aDbsname) {
		PoolData pooldata = getPoolData(aDbsname);
		return getDao(pooldata);
	}
	
	// ----


	private PoolData build(RegisterDatabase aRegisterDbs) {
		try {
			PoolData result = new PoolData();
			result.registerDatabase = aRegisterDbs;
			result.daoFactory = result.registerDatabase.getDaoFactory();
			return result;
		} catch (Exception e) {
			logger.error("error in ConnPoolsImpl.build " + e);
			throw new RuntimeException(e);
		}
	}

	private PoolData getPoolData(String aDbsname) {
		PoolData result = mDbsMap.get(aDbsname);
		if (result != null) {
			return result;
		} else {
			throw new RuntimeException("no database registered with the name " + aDbsname);
		}
	}
	
	private Dao getDao(PoolData pooldata) {
		return pooldata.daoFactory.build();
	}
	
	private class PoolData {
		RegisterDatabase registerDatabase;
		DaoFactory daoFactory;
	}
	
}
